﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Labthink.PCSoft.UniversalHost4.DataAccess;
using Labthink.PCSoft.UniversalHost4.Model;
using Labthink.PCSoft.UniversalHost4.Model.Query;
using Labthink.PCSoft.UniversalHost4.Model.User;
using Labthink.PCSoft.UniversalHost4.UserControls.MsgBox;
using Labthink.PCSoft.UniversalHost4.Utility;

namespace Labthink.PCSoft.UniversalHost4.UserControls
{
    public partial class UcUserManage
    {
        private QueryUser _qu;
        private const int PageSize = 10;
        private NotifyManager _notify;
        private Window _owner;

        public ObservableCollection<UserInfo> Users { get; } =
            new ObservableCollection<UserInfo>(new List<UserInfo>());

        public UcUserManage()
        {
            DataContext = this;
            InitializeComponent();
            btnAddUser.Focus();
            pager.OnPageIndexChanged += (sender, args) =>
            {
                var r = GetUsers(pager.PageIndex);
                UpdatePager(r);
            };

            Title = LanguageManager.GetLanguageValue("UserMgmtWindowTitle");
        }

        public string Title { get; set; }

        public string PermissionCode { get; set; } = "Per_UserMgmt";

        private void UpdatePager(PagingInfo pi)
        {
            pager.TotalItemCount = pi.TotalItemCount;
            pager.TotalPageCount = pi.TotalPageCount;
        }

        void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            if (!(e.Row.Item is UserInfo user)) return;
            if (user.UserName == Common.CurrentUser.UserName) e.Row.IsEnabled = false;
            if (user.IsLock.HasValue && user.IsLock.Value) e.Row.Background = Brushes.LightGray;
            if (user.IsDelete.HasValue && user.IsDelete.Value) e.Row.Background = Brushes.Red;
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            var user = ((Button)sender).CommandParameter as UserInfo;
            if (user == null) return;
            var isDeleted = user.IsDelete ?? false;
            if (isDeleted)
            {
                if (MyMessageBox.Show(_owner, LanguageManager.GetLanguageValue("Confirm_NewUser", user.UserName), MyMessageBoxButton.OkCancel, MyMessageBoxImage.Warning, MyMessageBoxDefaultButton.Ok) != MyMessageBoxResult.Ok) return;
            }
            else
            {
                if (MyMessageBox.Show(_owner, LanguageManager.GetLanguageValue("Confirm_DelUser", user.UserName), MyMessageBoxButton.OkCancel, MyMessageBoxImage.Question, MyMessageBoxDefaultButton.Ok) != MyMessageBoxResult.Ok) return;
            }

            if (isDeleted)
            {
                // 恢复用户
                try
                {
                    UserRepository.DeleteUser(user.LoginName, false);
                    LogRepository.AddLog(LanguageManager.GetLanguageValue("OP-RenewUser", user.LoginName), "Manage");
                    _notify.ShowSuccess(LanguageManager.GetLanguageValue("ActionSuccess"));
                }
                catch (Exception ex)
                {
                    _notify.ShowError(ex.Message);
                }
            }
            else
            {
                // 删除用户
                try
                {
                    // 若用户被锁定,首先解锁用户
                    var u = UserRepository.GetUser(user.LoginName).SingleOrDefault(ux => ux.LoginName == user.LoginName);
                    if (u?.IsLock != null && u.IsLock.Value)
                    {
                        UserRepository.LockUser(user.LoginName, false);
                    }

                    UserRepository.DeleteUser(user.LoginName, true);
                    LogRepository.AddLog(LanguageManager.GetLanguageValue("OP-DeleteUser", user.LoginName), "Manage");
                    _notify.ShowSuccess(LanguageManager.GetLanguageValue("ActionSuccess"));
                }
                catch (Exception ex)
                {
                    _notify.ShowError(ex.Message);
                }
            }

            pager.PageIndex = 1;
            pager.TotalPageCount = 1;
            _qu.PageIndex = 0;
            PagingInfo r = GetUsers();
            UpdatePager(r);

            TxtUser.Focus();
        }

        private void btnModify_Click(object sender, RoutedEventArgs e)
        {
            var user = ((Button)sender).CommandParameter as UserInfo;
            var mu = new AddUser { Info = user };
            var dr = mu.ShowDialog(Application.Current.MainWindow);

            if (dr.HasValue && dr.Value)
            {
                _notify.ShowSuccess(mu.ActionMsg);
                var r = GetUsers();
                UpdatePager(r);
            }
        }

        private void btnLock_Click(object sender, RoutedEventArgs e)
        {
            if (!(((Button)sender).CommandParameter is UserInfo user)) return;

            if (user.IsLock.HasValue && user.IsLock.Value)
            {
                //解锁操作
                if (MyMessageBox.Show(_owner, string.Format(LanguageManager.GetLanguageValue("Confirm_UnlockUser"), user.UserName),
                        MyMessageBoxButton.OkCancel, MyMessageBoxImage.Question, MyMessageBoxDefaultButton.Ok) !=
                    MyMessageBoxResult.Ok) return;
                try
                {
                    UserRepository.LockUser(user.LoginName, false);
                    LogRepository.AddLog(LanguageManager.GetLanguageValue("OP-UnlockUser", user.LoginName), "Manage");
                    _notify.ShowSuccess(LanguageManager.GetLanguageValue("ActionSuccess"));
                }
                catch (Exception ex)
                {
                    _notify.ShowError(ex.Message);
                }
                user.IsLock = false;
            }
            else
            {
                //锁定操作
                if (MyMessageBox.Show(_owner, string.Format(LanguageManager.GetLanguageValue("Confirm_LockUser"), user.UserName), MyMessageBoxButton.OkCancel, MyMessageBoxImage.Question, MyMessageBoxDefaultButton.Ok) != MyMessageBoxResult.Ok) return;
                try
                {
                    UserRepository.LockUser(user.LoginName, true);
                    LogRepository.AddLog(LanguageManager.GetLanguageValue("OP-LockUser", user.LoginName), "Manage");
                    _notify.ShowSuccess(LanguageManager.GetLanguageValue("ActionSuccess"));
                }
                catch (Exception ex)
                {
                    _notify.ShowError(ex.Message);
                }

                user.IsLock = true;
            }
            GetUsers(_qu);
        }

        private void btnResetPassword_Click(object sender, RoutedEventArgs e)
        {
            if (!(((Button)sender).CommandParameter is UserInfo user)) return;
            if (MyMessageBox.Show(_owner, string.Format(LanguageManager.GetLanguageValue("Confirm_ResetPassword"), user.UserName), MyMessageBoxButton.OkCancel, MyMessageBoxImage.Question, MyMessageBoxDefaultButton.Ok) != MyMessageBoxResult.Ok) return;
            try
            {
                UserRepository.ResetPassword(user.LoginName);
                LogRepository.AddLog(LanguageManager.GetLanguageValue("OP-ResetUserPwd", user.LoginName), "Manage");
                _notify.ShowSuccess(LanguageManager.GetLanguageValue("ActionSuccess"));
            }
            catch (Exception ex)
            {
                _notify.ShowError(ex.Message);
            }
        }

        private void Control_Loaded(object sender, RoutedEventArgs e)
        {
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }

            _owner = Window.GetWindow(this);
            _notify = NotifyManager.InstanceManager(_owner);

            LoadData.Visibility = Visibility.Collapsed;
            btnSearch.IsEnabled = false;
            pager.PageIndex = 1;
            pager.ItemCountPerPage = PageSize;
            DataContext = Users;

            _qu = new QueryUser
            {
                PageIndex = 1,
                PageCount = PageSize,
                User = "",
            };

            bool rr = GetRoles();

            if (rr == false)
            {
                return;
            }

            PagingInfo r = GetUsers(_qu);
            UpdatePager(r);
            btnSearch.IsEnabled = true;
        }

        private PagingInfo GetUsers(int pageIndex)
        {
            _qu.PageIndex = pageIndex;
            return GetUsers(_qu);
        }

        private PagingInfo GetUsers()
        {
            return GetUsers(_qu);
        }

        private bool GetRoles()
        {
            List<Role> roles = RoleAndPerRepository.GetRoles();
            if (roles == null || !roles.Any())
            {
                return false;
            }

            var listRoles = new List<ComboData>();
            listRoles.Add(new ComboData { Id = -1, Value = "--" });
            foreach (Role ro in roles)
            {
                listRoles.Add(new ComboData { Id = ro.Id, Value = ro.Name });
            }

            TxtRole.Init(listRoles, "Value", "Id");

            TxtRole.CbbChildBox.SelectedIndex = 0;
            return true;
        }

        private PagingInfo GetUsers(QueryUser qu)
        {
            ShowLoading();
            Users.Clear();
            DgUsers.Items.Refresh();
            PagedList<UserInfo> plu = UserRepository.GetUser(qu.User, qu.Role, qu.PageIndex, qu.PageCount);

            if (plu.InnerList == null || !plu.InnerList.Any())
            {
                HideLoading();
                return new PagingInfo(0, 0);
            }

            List<UserInfo> users = plu.InnerList.ToList();
            Users.Clear();

            foreach (UserInfo u in users)
            {
                Users.Add(u);
            }

            DgUsers.ItemsSource = Users;

            HideLoading();
            return new PagingInfo
            {
                TotalItemCount = plu.TotalCount,
                TotalPageCount = plu.PageCount
            };
        }

        private void btnAddUser_OnClick(object sender, RoutedEventArgs e)
        {
            if (TxtRole.CbbChildBox.Items.Count <= 0)
            {
                _notify.ShowError(LanguageManager.GetLanguageValue("AddRoleFirst"));
                return;
            }

            var au = new AddUser();
            var dr = au.ShowDialog(Application.Current.MainWindow);
            if (dr.HasValue && dr.Value)
            {
                _notify.ShowSuccess(au.ActionMsg);
                PagingInfo r = GetUsers();
                UpdatePager(r);
            }
        }

        private void BtnSearch_OnClick(object sender, RoutedEventArgs e)
        {
            Users.Clear();
            UpdatePager(new PagingInfo(0, 0));

            _qu.PageIndex = 1;
            _qu.User = TxtUser.Value;
            if (TxtRole.SelectedItem != null)
            {
                _qu.Role = ((ComboData)TxtRole.SelectedItem).Id;
            }

            if (_qu.Role == -1)
            {
                _qu.Role = null;
            }

            PagingInfo r = GetUsers();
            pager.PageIndex = 1;
            UpdatePager(r);
        }

        private void BtnReset_OnClick(object sender, RoutedEventArgs e)
        {
            TxtUser.Value = "";
            TxtRole.CbbChildBox.SelectedIndex = 0;

            _qu.User = "";
            _qu.Role = null;
            _qu.PageIndex = 1;
            _notify.ShowSuccess(LanguageManager.GetLanguageValue("ActionSuccess"));
            BtnSearch_OnClick(null, null);
            TxtUser.Focus();
        }

        private void LoadData_OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var isEnabled = sender is Loading loading && loading.Visibility == Visibility.Collapsed;
            var controls = new List<Control>
            {
                btnSearch,
                btnReset,
                btnAddUser,
                pager,
            };

            foreach (Control c in controls)
            {
                c.IsEnabled = isEnabled;
            }
        }

        private void ShowLoading()
        {
            LoadData.Visibility = Visibility.Visible;
        }

        private void HideLoading()
        {
            LoadData.Visibility = Visibility.Collapsed;
        }
    }
}
